<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2017/1/17 0017
 * Time: 15:01
 */

namespace core\MNS;

use think\Log;
require_once( EXTEND_PATH . '/core/Mns/mns-autoloader.php' );
use AliyunMNS\Client;
use AliyunMNS\Exception\MnsException;


class MNS
{
    public static $client = '';
    public static $queue = '';
    public static $res = '';
    public static $receiptHandle = '';

    /**
     * MNS constructor.
     * 构造函数 初始化socket链接
     */
    public function __construct()
    {
        self::$client = new Client(config('mns.endPoint'), config('mns.accessId'), config('mns.accessKey') );
    }

    /**
     * 接收队列信息 返回数据
     * @param string $queueName 队列名
     * @return \AliyunMNS\Responses\ReceiveMessageResponse|bool|string
     */
    public static function receive($queueName = "lianpiao")
    {
        self::$queue = self::$client->getQueueRef($queueName);
        try {
            // when receiving messages, it's always a good practice to set the waitSeconds to be 30.
            // it means to send one http-long-polling request which lasts 30 seconds at most.
            self::$res = self::$queue->receiveMessage(2);
            // 2. 获取ReceiptHandle，这是一个有时效性的Handle，可以用来设置Message的各种属性和删除Message。具体的解释请参考：help.aliyun.com/document_detail/27477.html 页面里的ReceiptHandle
            self::$receiptHandle = self::$res->getReceiptHandle();

            //业务处理 稍后补充提取数据
            return self::$res;
        } catch (MnsException $e) {
            Log::write("ReceiveMessage Failed: " . $e, 'notice');
            return false;
        }
    }

    /**
     * 删除队列消息
     * 消息接收完，将处于不活跃状态的消息删除 如果不删除，消息将在5分钟后由不活跃转为活跃状态重新进入队列
     * @return bool
     */
    public static function del()
    {
        // 4. 现在消息已经处理完了。我们可以从队列里删除这条消息了。
        try
        {
            // 5. 直接调用deleteMessage即可。
            self::$res = self::$queue->deleteMessage(self::$receiptHandle);
            return true;
        }
        catch (MnsException $e)
        {
            // 6. 这里CatchException并做异常处理
            // 6.1 如果是receiptHandle已经过期，那么ErrorCode是MessageNotExist，表示通过这个receiptHandle已经找不到对应的消息。
            // 6.2 为了保证receiptHandle不过期，VisibilityTimeout的设置需要保证足够消息处理完成。并且在消息处理过程中，也可以调用changeMessageVisibility这个函数来延长消息的VisibilityTimeout时间。
            $info = "DeleteMessage Failed: " . $e . "\n" . "MNSErrorCode: " . $e->getMnsErrorCode() . "\n";
            Log::write($info, 'notice');
            return false;
        }
    }

    /**
     * 发送消息至陶静
     * @param string $queueName 队列名
     * @param string $messageBody 消息内容
     * @return bool
     */
    public static function send($queueName = "lianpiao", $messageBody = "test")
    {
        // 1. 首先获取Queue的实例
        // 1.1 PHP SDK默认会对发送的消息做Base64 Encode，对接收到的消息做Base64 Decode。
        // 1.2 如果不希望SDK做这样的Base64操作，可以在getQueueRef的时候，传入参数$base64=FALSE。即$queue = $this->client->getQueueRef($queueName, FALSE);
        self::$queue = self::$client->getQueueRef($queueName);
        // 2. 生成一个SendMessageRequest对象
        // 2.1 SendMessageRequest对象本身也包含了DelaySeconds和Priority属性可以设置。
        // 2.2 对于Message的属性，请参考help.aliyun.com/document_detail/27477.html
        $request = new SendMessageRequest($messageBody);
        try
        {
            $res = self::$queue->sendMessage($request);
            return true;
        }
        catch (MnsException $e)

        {
            // 4. 可能因为网络错误，或MessageBody过大等原因造成发送消息失败，这里CatchException并做对应的处理。
            echo "SendMessage Failed: " . $e . "\n";
            echo "MNSErrorCode: " . $e->getMnsErrorCode() . "\n";
            $info = "SendMessage Failed: " . $e . "\n" . "MNSErrorCode: " . $e->getMnsErrorCode() . "\n";
            Log::write($info, 'notice');
            return false;
        }
    }
}